/*
 * @Author: lsmi
 * @Date: 2021-11-05 12:42:37
 * @LastEditors: lsmi
 * @LastEditTime: 2021-11-05 21:44:48
 * @FilePath: \base-typescript\src\error.ts
 */
function parse() {
  // 抛出异常
  throw new RangeError('error')
}
// 自定义错误类型
class InvalidDateFormatError extends ReferenceError { }
class DateIsInTheFutureError extends ReferenceError { }
function parses() {
  throw new InvalidDateFormatError('xxx')
}
try {

} catch (e) {
  if (e instanceof InvalidDateFormatError) {
    console.error(e.message)
  } else if (e instanceof DateIsInTheFutureError) {
    console.info(e.message)
  } else {
    throw e
  }
}
/**
 * @throws { InvalidDateFormatError } xxxxxx
 * @throws { DateIsInTheFutureError } xxxxxx
 */
function parse1() {

}
parse1()

function isValid(date: Date){
  return Object.prototype.toString.call(date) === '[object Date]' && !Number.isNaN(date.getTime())
}
function parse2(bir: string): Date | InvalidDateFormatError | DateIsInTheFutureError {
  let date = new Date(bir)
  if (!isValid(date)) {
    return new InvalidDateFormatError('InvalidDateFormatError')
  }
  if (date.getTime() > Date.now()) {
    return new DateIsInTheFutureError('DateIsInTheFutureError')
  }
  return date
}
function ap() {
  let res = parse2('s') // 这里ts不报错
  if (res instanceof InvalidDateFormatError) {

  }
}


interface Option<T>{
  flatMap<U>(f: (value: T) => Option<U>): Option<U>
  getOrElse(value: T): T
}
class Some<T> implements Option<T>{
  constructor(private value: T){}
  flatMap<U>(f: (value: T) => Option<U>): Option<U>{
    return f(this.value)
  }
  getOrElse(): T{
    return this.value
  }
}
class None implements Option<never>{
  flatMap<U>(): Option<U>{
    return this
  }
  getOrElse<U>(value: U): U{
    return value
  }
}
